package filescript;
import actions.*;
import filters.*;
import java.io.*;
import java.util.*;

public class MyFileScript {
	
	private final static String FILTER_IDENTIFIER="FILTERS";
	private final static String ACTION_IDENTIFIER="ACTION";
	private final static String COMMENT_IDENTIFIER="#";
	
	private static void addFileToTreeSet(TreeSet<File> ts,File file) {
		File[] _filesInDir = file.listFiles();
		for(int i=0;i<_filesInDir.length;i++) {
			if(_filesInDir[i].isDirectory()) {
				addFileToTreeSet(ts,_filesInDir[i]);
			} else {
				ts.add(_filesInDir[i]);
			}
		}
	}
	
	private static TreeSet<File> readDirectory(String path) {
		TreeSet<File> ts = new TreeSet<File>();
		File _dirPath = new File(path);
		addFileToTreeSet(ts,_dirPath);
		return ts;
	}
	
	private static void parseCommandLineFile(ArrayList<FilterAndAction> dest,BufferedReader fileBuffer ,TreeSet<File> globalSet) throws IOException, InvalidSectionException, InvalidCommandLineParametersException {
		FilterAndAction fa = new FilterAndAction(globalSet);
		String nextLine = fileBuffer.readLine();
		
		while(fileBuffer.ready()) {
			if(!nextLine.equals(FILTER_IDENTIFIER)) {
				throw new InvalidSectionException();
			} else {
				nextLine = fileBuffer.readLine();
			}
			while(!nextLine.equals(ACTION_IDENTIFIER) && fileBuffer.ready()) {
				if(nextLine.startsWith(COMMENT_IDENTIFIER)) {
					fa.addComment(nextLine);
				} else {
					fa.addFilter(nextLine);
				}
					nextLine = fileBuffer.readLine();
			}
			if(nextLine.equals(ACTION_IDENTIFIER)) {
				nextLine = fileBuffer.readLine();
				if(nextLine.startsWith(COMMENT_IDENTIFIER)) {
					throw new InvalidSectionException();
				}
				fa.setAction(nextLine);
			}
			dest.add(fa);
			nextLine = fileBuffer.readLine();
			fa = new FilterAndAction(globalSet);
		}
	}
	
	
	public static void main(String[] args) throws UnsupportedFilterException, InvalidFilterParameterException, InvalidActionParametersException, FileNotFoundException, IOException{
		ArrayList<FilterAndAction> filterActionGroups = new ArrayList<FilterAndAction>();
		TreeSet<File> globalSet = readDirectory(args[0]);
		FileInputStream inStream = new FileInputStream(args[1]);
		InputStreamReader inReader = new InputStreamReader(inStream);
		BufferedReader buffReader = new BufferedReader(inReader);
		try {
			/**
			 * Call the static method to parse the command line in to an Array of FilerAndAction objects
			 */
			parseCommandLineFile(filterActionGroups,buffReader,globalSet);
			
			/**
			 * Validate the structure, filters and actions before executing actions
			 */
			for(FilterAndAction f:filterActionGroups) {
				f.verifySectionBuild();
				f.parseFilters();
				f.validateAction();
			}
			/**
			 * If no exception was thrown, Iterate the groups, print the comments and perform the action
			 */
			for(FilterAndAction f:filterActionGroups) {
				f.printComments();
				f.executeAction();
			}
			
		} catch (IOException e) {
			System.err.println(e.toString());
		} catch (InvalidSectionException e) {
			System.err.println(e.toString());
		} catch (InvalidFilterExpression e) {
			System.err.println(e.toString());
		} catch (UnsupportedFilterException e) {
			System.err.println(e.toString());
		} catch (InvalidActionException e) {
			System.err.println(e.toString());
		} catch (InvalidCommandLineParametersException e) {
			System.err.println(e.toString());
		} catch (InvalidFilterParameterException e) {
			System.err.println(e.toString());
		}
		finally {
			/**
			 * If an exception was raised (NOT IOException) close the files and streams
			 */
			buffReader.close();
			inReader.close();
			inStream.close();
		}
	}
}
